package com.liugh.config;

import com.liugh.base.BusinessException;
import com.liugh.base.PublicResultConstant;
import com.liugh.controller.BaseRestController;
import com.liugh.exception.FileDownloadException;
import com.liugh.exception.FileNotExistException;
import com.liugh.exception.ParamJsonException;
import com.liugh.exception.UnauthorizedException;
import org.apache.shiro.ShiroException;
import org.csource.common.MyException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartException;

/**
 * Controller统一异常处理
 * @author : liugh
 * @date : 2018/05/08
 */
@ControllerAdvice
public class AllControllerAdvice {
    private static Logger logger = LoggerFactory.getLogger(AllControllerAdvice.class);

    /**
     * 应用到所有@RequestMapping注解方法，在其执行之前初始化数据绑定器
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {
    }

    /**
     * 把值绑定到Model中，使全局@RequestMapping可以获取到该值
     */
    @ModelAttribute
    public void addAttributes(Model model) {
    }

    /**
     * 全局异常捕捉处理
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ResponseModel<String> errorHandler(Exception ex) {
        ex.printStackTrace();
        logger.error("接口出现严重异常：{}", ex.getMessage());
        return BaseRestController.fillFailData(PublicResultConstant.FAILED);
    }

    /**
     * 捕捉UnauthorizedException
     * @return
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(UnauthorizedException.class)
    @ResponseBody
    public ResponseModel<String> handleUnauthorized() {
        return BaseRestController.validationFailure(PublicResultConstant.USER_NO_PERMITION);
    }

    /**
     * 捕捉shiro的异常
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(ShiroException.class)
    @ResponseBody
    public ResponseModel<String> handleShiroException(ShiroException e) {
        return BaseRestController.validationFailure(PublicResultConstant.USER_NO_PERMITION);
    }

    /**
     * 捕捉BusinessException自定义抛出的异常
     * @return
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public ResponseModel handleBusinessException(BusinessException e) {
        if(e instanceof BusinessException) {
            logger.info("数据操作失败："+e.getMessage());
            return BaseRestController.fillFailData("数据操作失败："+e.getMessage());
        }
        return BaseRestController.fillFailData(PublicResultConstant.ERROR);
    }

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(value = ParamJsonException.class)
    @ResponseBody
    public ResponseModel<String> handleParamJsonException(Exception e) {
        if(e instanceof ParamJsonException) {
            logger.info("参数错误："+e.getMessage());
            return BaseRestController.fillFailData("参数错误："+ e.getMessage());
        }
        return BaseRestController.fillFailData(PublicResultConstant.ERROR);
    }


    //捕获上传文件异常
    @ExceptionHandler(MyException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public ResponseModel<String> handleUploadFileExcoetion(Exception e) {
        if (e instanceof MyException || e instanceof MultipartException) {
            logger.info("文件上传失败：" + e.getMessage());
            return BaseRestController.fillFailData(e.getMessage());
        }
        return BaseRestController.fillFailData(PublicResultConstant.UPLOAD_FILE_FAIL);
    }

    //捕获下载文件时文件不存在异常
    @ExceptionHandler(value = FileNotExistException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public ResponseModel<String> handleFileNotExistExcpetion(Exception e) {
        if (e instanceof FileNotExistException) {
            logger.info("文件不存在：" + e.getMessage());
            return BaseRestController.fillFailData(e.getMessage());
        }
        return BaseRestController.fillFailData(PublicResultConstant.FILE_NOT_EXIST);
    }

    //捕获下载文件失败异常
    @ExceptionHandler(value = FileDownloadException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public ResponseModel<String> handleFileDownloadException(Exception e) {
        if (e instanceof FileDownloadException) {
           logger.info("文件下载失败："+e.getMessage());
            return BaseRestController.fillFailData(e.getMessage());
        }
        return BaseRestController.fillFailData(PublicResultConstant.FILE_DOWNLOAD_FIAL);
    }


}